package com.xdl.flytest.service;

import com.xdl.flytest.bean.Report;
import com.xdl.flytest.bean.TestCase;

import com.xdl.flytest.dao.ReportMapper;
import com.xdl.flytest.dao.TestCaseMapper;
import com.xdl.flytest.util.runner.ReportUtil;
import com.xdl.flytest.util.runner.TestCaseRunner;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * @Auther: 80736
 * @Date: 2019/1/8 16:48
 * @Description:
 */
@Service
public class TestCaseService {
    @Autowired
    private TestCaseMapper testCaseMapper;

    @Autowired
    private ReportMapper reportMapper;

    @Autowired
    private SqlSessionTemplate batchSqlSession;

    @Autowired
    private MongoTemplate mongoTemplate;


    @Autowired
    private TestCaseRunner testCaseRunner;


    /**
     * 获取所有testcase
     * 包括testsuit interface信息
     * @return
     */
    public List<TestCase> getTestCases() {
        return testCaseMapper.selectTestCases();
    }

    /**
     * 获取所有testcase
     *
     * @return
     */
    public List<TestCase> getAllTestCases() {
        return testCaseMapper.selectAllTestCases();
    }

    /**
     * 根据id获得testcase
     * @param id
     * @return
     */
    public TestCase getTestCaseById(Integer id) {
        return testCaseMapper.selectByPrimaryKey(id);
    }

    /**
     * 根据对象更新testcase
     * @param testCase
     */
    public void updateTestCase(TestCase testCase) {
        testCaseMapper.updateByPrimaryKeySelective(testCase);
    }

    /**
     * 批量删除测试用例
     * @param idList
     */
    public void deleteTestCases(String[] idList) {
        SqlSessionFactory sqlSessionFactory = batchSqlSession.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        TestCaseMapper testCaseMapperBatch = sqlSession.getMapper(TestCaseMapper.class);
        for (String id : idList) {
            testCaseMapperBatch.deleteByPrimaryKey(Integer.parseInt(id));
        }
    }

    /**
     * 根据id删除用例
     *
     * @param id
     */
    public void deleteTestCase(Integer id) {
        testCaseMapper.deleteByPrimaryKey(id);
    }

    /**
     * 增加testcase
     *
     * @param testCase
     */
    public void addTestCase(TestCase testCase) {
        testCaseMapper.insertSelective(testCase);
    }

    /**
     * 根据用例id运行用例
     *
     * @param testCaseId
     * @return
     * @throws IOException
     */
    public boolean runTestCaseById(Integer testCaseId) throws IOException {

        TestCase testCase = testCaseMapper.selectByPrimaryKey(testCaseId);
        Report report = new Report();
        try {
            //初始化
            String containerId = testCaseRunner.init();
            // 运行测试
            testCaseRunner.run(containerId, testCase.getJsonData());
            // 保存测试报告到mysql
            saveReportToDB(testCaseId);
            return true;
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        } finally {
            testCaseRunner.cleanUp();
        }

        return false;
    }


    /**
     * 保存测试报告到db
     *
     * @param testCaseId
     * @throws IOException
     */
    private void saveReportToDB(Integer testCaseId) throws IOException {
        Report report = new Report();
        SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
        String now = sf.format(new Date());
        report.setReportName(String.format("TestCaseReport-%s", now));
        report.setReportText(ReportUtil.getReportHtml());
        report.setBelongTestCase(testCaseId);
        report.setCreateTime(new Date());
        reportMapper.insertSelective(report);
    }

    /**
     * 链接测试用例到测试集
     *
     * @param cid 测试用例id，前端可能传入一串用例id，用冒号:分割
     * @param sid 被关联的测试集
     */
    public boolean linkTestCaseToTestSuit(String cid, String sid) {
        if (cid != null && sid != null) {
            // 链接多个testcase
            if (cid.contains(":")) {
                String[] testcaseIdList = cid.split(":");
                for (String id : testcaseIdList) {
                    TestCase testCase = testCaseMapper.selectByPrimaryKey(Integer.parseInt(id));
                    // 被关联的用例所属的testsuit和当前testsut id相同，则跳过关联
                    if (sid.equals(testCase.getTestSuitId())) {
                        continue;
                    } else {
                        // 被关联的testcase不属于当前testsuit,则复制一条testcase，插入MySQL
                        testCase.setTestcaseId(null);
                        testCase.setTestSuitId(Integer.parseInt(sid));
                        testCaseMapper.insertSelective(testCase);
                    }
                }
            } else {
                // 链接一个单独的testcase
                TestCase testCase = testCaseMapper.selectByPrimaryKey(Integer.parseInt(cid));
                if (!sid.equals(testCase.getTestSuitId())) {
                    testCase.setTestcaseId(null);
                    testCase.setTestSuitId(Integer.parseInt(sid));
                    testCaseMapper.insertSelective(testCase);
                }
            }
            return true;
        }
        return false;
    }
}
